package edu.umn.contactviewer;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OptionalDataException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import android.content.Context;
import android.widget.Toast;

/**
 * This class saves, updates, deletes, and reads from a serialized datastore
 * based on a simle hashmap..
 * 
 */
public class ContactsDB {

	// linked to preserve ordering.
	static HashMap<String, Contact> contactsMap = new LinkedHashMap<String, Contact>();

	/**
	 * @param ctx
	 *            Context is required to access serialized datastore
	 * @return All of the stored contacts
	 */
	@SuppressWarnings("unchecked")
	public synchronized static Map<String, Contact> getContacts(Context ctx) {

		GetContactsTask task = new GetContactsTask();
		task.execute(new String[] {});

		List<Contact> contacts = null;
		try {
			contacts = task.get().getContacts();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		for (Contact c : contacts) {
			contactsMap.put(c.getName(), c);
		}

		Toast.makeText(ctx, "Retrieved " + contacts.size() + " contacts.",
				Toast.LENGTH_LONG).show();

		return contactsMap;
	}

	/**
	 * Saves the contact into the database.
	 * 
	 * @param currentContact
	 *            the contact to store.
	 * @param ctx
	 *            Context is required to access serialized datastore
	 * 
	 * @return Whether the save was successful
	 */
	public static synchronized boolean put(Contact currentContact, Context ctx) {
		if (contactsMap.containsKey(currentContact.getName())) {
			return false;
		} else {

			AddContactTask task = new AddContactTask();
			task.execute(new Contact[] { currentContact });

			Contact c = null;
			try {
				c = task.get();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ExecutionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			if (c.getStatus().equals("success")) {

				contactsMap.put(currentContact.getName(), currentContact);
				return true;
			}

			return false;
		}

	}

	/**
	 * Update the contact into the database.
	 * 
	 * @param currentContact
	 *            the contact to update.
	 * @param ctx
	 *            Context is required to access serialized datastore
	 * 
	 */
	public static synchronized void update(Contact currentContact, Context ctx) {

		UpdateContactTask task = new UpdateContactTask();
		task.execute(new Contact[] { currentContact });

		Contact c = null;
		try {
			c = task.get();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		if (c.getStatus().equals("success")) {

			contactsMap.put(currentContact.getName(), currentContact);

		} else {
			Toast.makeText(ctx, "Update was unsuccessful.  Try again.",
					Toast.LENGTH_LONG).show();
		}

	}

	/**
	 * Remove the contact from the database.
	 * 
	 * @param currentContact
	 *            the contact to remove from the store.
	 * @param ctx
	 *            Context is required to access serialized datastore
	 */
	public static synchronized void remove(Contact currentContact, Context ctx) {
		

		DeleteContactTask task = new DeleteContactTask();
		task.execute(new Contact[] { currentContact });

		Contact c = null;
		try {
			c = task.get();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		if (c.getStatus().equals("success")) {
			contactsMap.remove(currentContact.getName());
		} else {
			Toast.makeText(ctx, "Delete was unsuccessful.  Try again.",
					Toast.LENGTH_LONG).show();
		}
	}

}
